using System;
using System.IO;
using System.Net;
using System.Threading;
using BanZuiCloudControlAgent.Utils.Logging;

namespace BanZuiCloudControlAgent.Utils.Exceptions.Example
{
    /// <summary>
    /// 异常处理示例类
    /// </summary>
    public class ExceptionExample
    {
        /// <summary>
        /// 演示如何使用自定义异常类
        /// </summary>
        public static void DemoCustomExceptions()
        {
            Console.WriteLine("=== 自定义异常示例 ===");

            try
            {
                // 模拟网络异常
                ThrowNetworkException();
            }
            catch (NetworkException ex)
            {
                Console.WriteLine($"捕获到网络异常: {ex}");
                Console.WriteLine($"错误类型: {ex.ErrorType}");
                Console.WriteLine($"错误代码: {ex.ErrorCode}");
                Console.WriteLine($"模块: {ex.Module}");
                Console.WriteLine();
            }

            try
            {
                // 模拟EMQX异常
                ThrowEmqxException();
            }
            catch (EmqxException ex)
            {
                Console.WriteLine($"捕获到EMQX异常: {ex}");
                Console.WriteLine($"错误类型: {ex.ErrorType}");
                Console.WriteLine($"主题: {ex.Topic}");
                Console.WriteLine();
            }

            try
            {
                // 模拟QQ异常
                ThrowQQException();
            }
            catch (QQException ex)
            {
                Console.WriteLine($"捕获到QQ异常: {ex}");
                Console.WriteLine($"错误类型: {ex.ErrorType}");
                Console.WriteLine($"QQ账号: {ex.QQAccount}");
                Console.WriteLine();
            }

            try
            {
                // 模拟配置异常
                ThrowConfigurationException();
            }
            catch (ConfigurationException ex)
            {
                Console.WriteLine($"捕获到配置异常: {ex}");
                Console.WriteLine($"错误类型: {ex.ErrorType}");
                Console.WriteLine($"配置键: {ex.ConfigKey}");
                Console.WriteLine();
            }

            try
            {
                // 模拟任务异常
                ThrowTaskException();
            }
            catch (TaskException ex)
            {
                Console.WriteLine($"捕获到任务异常: {ex}");
                Console.WriteLine($"错误类型: {ex.ErrorType}");
                Console.WriteLine($"任务ID: {ex.TaskId}");
                Console.WriteLine();
            }
        }

        /// <summary>
        /// 演示如何使用异常处理器
        /// </summary>
        public static void DemoExceptionHandler()
        {
            Console.WriteLine("=== 异常处理器示例 ===");

            // 创建异常处理器
            var logger = LogManager.GetLogger("ExceptionExample");
            var handler = new ExceptionHandler(logger, false);

            // 处理标准异常
            var standardEx = new IOException("文件访问失败");
            bool isFatal = handler.Handle(standardEx, "IO操作");
            Console.WriteLine($"标准异常是否致命: {isFatal}");
            Console.WriteLine();

            // 处理自定义异常
            var customEx = new NetworkException(NetworkErrorType.ConnectionFailed, "连接服务器失败");
            isFatal = handler.Handle(customEx, "网络操作");
            Console.WriteLine($"自定义异常是否致命: {isFatal}");
            Console.WriteLine();

            // 处理带有内部异常的自定义异常
            var innerEx = new WebException("无法连接到服务器");
            var customExWithInner = new EmqxException(
                EmqxErrorType.ConnectionFailed,
                "emqx/device/status",
                "EMQX连接失败",
                innerEx
            );
            isFatal = handler.Handle(customExWithInner, "EMQX操作");
            Console.WriteLine($"带内部异常的自定义异常是否致命: {isFatal}");
            Console.WriteLine();

            // 处理致命异常
            var fatalEx = new BanZuiException("E999", "Core", "系统核心组件崩溃", true);
            isFatal = handler.Handle(fatalEx, "核心组件");
            Console.WriteLine($"致命异常是否致命: {isFatal}");
        }

        /// <summary>
        /// 演示如何在实际代码中使用异常处理
        /// </summary>
        public static void DemoRealWorldUsage()
        {
            Console.WriteLine("=== 实际使用示例 ===");

            try
            {
                // 模拟连接EMQX服务器
                Console.WriteLine("尝试连接EMQX服务器...");
                ConnectToEmqx("mqtt.example.com", 1883, "username", "password");
                Console.WriteLine("连接成功");
            }
            catch (EmqxException ex) when (ex.ErrorType == EmqxErrorType.ConnectionFailed)
            {
                Console.WriteLine($"连接失败: {ex.Message}");
                Console.WriteLine("尝试使用备用服务器...");
                
                try
                {
                    ConnectToEmqx("backup.mqtt.example.com", 1883, "username", "password");
                    Console.WriteLine("备用连接成功");
                }
                catch (EmqxException backupEx)
                {
                    Console.WriteLine($"备用连接也失败了: {backupEx.Message}");
                    Console.WriteLine("放弃连接尝试");
                }
            }
            catch (EmqxException ex) when (ex.ErrorType == EmqxErrorType.AuthenticationFailed)
            {
                Console.WriteLine($"认证失败: {ex.Message}");
                Console.WriteLine("请检查用户名和密码");
            }
            catch (EmqxException ex)
            {
                Console.WriteLine($"其他EMQX错误: {ex.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"未知错误: {ex.Message}");
            }
        }

        #region 模拟抛出异常的方法

        private static void ThrowNetworkException()
        {
            throw new NetworkException(NetworkErrorType.ConnectionFailed, "无法连接到服务器");
        }

        private static void ThrowEmqxException()
        {
            throw new EmqxException(EmqxErrorType.PublishFailed, "device/status", "发布消息失败");
        }

        private static void ThrowQQException()
        {
            throw new QQException(QQErrorType.LoginFailed, "123456789", "登录失败，可能需要验证码");
        }

        private static void ThrowConfigurationException()
        {
            throw new ConfigurationException(ConfigErrorType.KeyNotFound, "EMQX:ServerUrl", "配置项不存在");
        }

        private static void ThrowTaskException()
        {
            throw new TaskException(TaskErrorType.TaskFailed, "TASK-001", "任务执行失败");
        }

        private static void ConnectToEmqx(string server, int port, string username, string password)
        {
            // 模拟连接失败
            throw new EmqxException(EmqxErrorType.ConnectionFailed, "无法连接到EMQX服务器");
        }

        #endregion
    }
} 